home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / whereis.aqm / whereis.asm
Assembly Source File  |  1985-09-10  |  16KB  |  510 lines

  1. CG      GROUP CODE_SEG
  2.         ASSUME CS:CG, DS:CG
  3.  
  4. ; PAGE 101 SOFTALK, JAN 1984
  5. ; This pprogram will search all directories for a given filename and print
  6. ; the full path name of each one found
  7. ; REVISIONS
  8. ; The scrolling limitation of 23 lines and the More? prompt with its N key
  9. ; exit were added by Ted Eyrick, Eytek, Inc., P.O. Box 160307, San Antonio,
  10. ; Texas  78280.
  11.  
  12. DTA     STRUC
  13. ; This is the format for the DOS Data Transfer Area used when DOS 2.0
  14. ; searches for a file match in directories
  15.  
  16.         RESERVED        DB      21 DUP (?)
  17.         ATTRIBUTE       DB
  18.         TIME            DW
  19.         DATE            DW
  20.         SIZE            DD
  21.         NAME_FOUND      DB      13 DUP (?)
  22. DTA     ENDS
  23.  
  24.  
  25. CODE_SEG        SEGMENT
  26. ; This is the main program that sets up the initial conditions for
  27. ; SEARCH_DIRECTORY which, in turn, does a recursive search.
  28. ; Reads:        PATH_NAME
  29. ; Writes:       FILE_NAME
  30. ; Calls:        SEARCH_DIRECTORY
  31.  
  32.                 ORG 100H
  33.  
  34. START:
  35.         PUSH    AX
  36.         MOV     AH,30H
  37.         INT     21H
  38.         CMP     AL,2                    ; Is it at least 2.0 ?
  39.         JAE     VERS_OK
  40.         MOV     DX,OFFSET WRONG_VERS
  41.         CALL    ERROR
  42.         INT     20H
  43. VERS_OK:
  44.         MOV     AH,19H
  45.         INT     21H                     ; Get the current drive #
  46.         MOV     [OLDDRIV],AL            ; Save it
  47.         POP     AX
  48.         CMP     AL,-1                   ; Is a valid drive named ?
  49.         MOV     DX,OFFSET CG:INVALID_DRIVE
  50.         JNE     TEST_UP
  51. BAD_DRIVE:
  52.         CALL    ERROR
  53.         MOV     AL,2                    ; Error exit code
  54.         JMP     DOS_EXIT
  55. TEST_UP:
  56.         CMP     AH,-1
  57.         JE      BAD_DRIVE
  58.         MOV     SI,80H
  59.         CMP     BYTE PTR[SI],0          ; Any name specified
  60. NO_FILE:
  61.         MOV     DX,OFFSET CG:NONAME
  62.         JE      BAD_DRIVE
  63.  
  64. PARSE_FILE:
  65.         MOV     DI,65H
  66.         MOV     CX,3
  67.         MOV     AL,'?'
  68.         REP     STOSB                   ; Put '.*' default
  69.         MOV     SI,[CMDLINE]
  70.         CALL    SCANOFF
  71.         JNC     GOOD_NAME
  72.         MOV     AL,0
  73.         JMP     DOS_EXIT
  74. GOOD_NAME:
  75.         CMP     BYTE PTR[SI],'\'    ; Was it a pathname ?
  76.         JNE     NO_PATH
  77.         CALL    NEXT_BLANK              ; Go to next filename
  78.         MOV     [CMDLINE],SI            ; Ignore pathnames
  79.         JMP     PARSE_FILE
  80. NO_PATH:
  81.         CMP     BYTE PTR [FIRST],0
  82.         JE      FIRST_TIME              ; Don't check first time around
  83. FIRST_TIME:
  84.         MOV     DX,SI
  85.         CALL    GET_CHAR_COUNT
  86.         MOV     DI,OFFSET SEARCH_NAME
  87.         PUSH    SI
  88.         REP     MOVSB
  89.         POP     SI
  90.         MOV     AL,0
  91.         STOSB                           ; Set search name
  92.         CALL    PRINT_FILE_SEP
  93.         MOV     DI,5CH
  94.         MOV     AH,29H
  95.         MOV     AL,9                    ; Ignore leading seps
  96.         INT     21H
  97.         CMP     BYTE PTR[SI],'\'    ; Was it a pathname ?
  98.         JNE     NO_PATH1
  99.         CALL    NEXT_BLANK              ; Go to next filename
  100.         MOV     [CMDLINE],SI
  101.         JMP     PARSE_FILE
  102. NO_PATH1:
  103.         MOV     [CMDLINE],SI            ; Save pointer for next time
  104.  
  105. WHEREIS         PROC    NEAR
  106.         MOV     SI,5CH                  ; FCB
  107.         LODSB
  108.         CMP     AL,0                    ; Is it default drive ?
  109.         JE      IS_DEFAULT
  110.         SUB     AL,1                    ; Convert to logical
  111.         MOV     DL,AL
  112.         MOV     [CURDRIVE],AL
  113.         MOV     AH,0EH
  114.         INT     21H                     ; Select new drive
  115.         JMP     SHORT SEARCH
  116. IS_DEFAULT:
  117.         MOV     AL,[OLDDRIV]
  118.         MOV     [CURDRIVE],AL           ; Save it
  119. SEARCH:
  120.         MOV DI,OFFSET CG:FILE_NAME
  121. GET_SEARCH_NAME:
  122.         CMP     SI,65H                  ; End of FCB name ?
  123.         JAE     DONE_READING_NAME
  124.         LODSB                           ; get first character
  125.         CMP AL,' '            ; Is it space
  126.         JE      GET_SEARCH_NAME
  127.         STOSB
  128.         JMP GET_SEARCH_NAME
  129. DONE_READING_NAME:
  130.         MOV     AL,'.'
  131.         STOSB
  132. READ_EXT:
  133.         CMP     SI,68H                  ; End of FCB ext ?
  134.         JAE     FCB_TO_ASCIZ
  135.         LODSB
  136.         CMP     AL,' '
  137.         JE      READ_EXT
  138.         STOSB
  139.         JMP     READ_EXT
  140. FCB_TO_ASCIZ:
  141.         XOR AL,AL                       ; write a 0 at the end
  142.         STOSB
  143.         MOV DI,OFFSET CG:PATH_NAME
  144.         CMP     BYTE PTR[FILE_NAME+1],0 ; Is there a file ?
  145.         JNE     SEARCH_FILE
  146.         MOV     AL,0
  147.         JMP     DOS_EXIT
  148. SEARCH_FILE:
  149.         OR AL,AL                        ; search for the zero at the end
  150.         CLD                             ; of PATH_NAME
  151.         MOV CX,64                       ; Max. length of scan for 0
  152.         REPNZ SCASB
  153.         MOV BX,DI
  154.         DEC BX
  155.         MOV DX,0                        ; DS:BX points to end of PATH-NAME
  156.         CALL SEARCH_DIRECTORY           ; now do the trcursive search
  157.         MOV     BYTE PTR[FIRST],-1      ; Now we`ll go again !
  158.         CALL    IS_MORE                 ; Is there more ?
  159.         JAE     FINISH
  160.         JMP     PARSE_FILE
  161. FINISH:
  162.         MOV     AL,0
  163.         JMP DOS_EXIT                    ; all done now
  164. WHEREIS ENDP
  165.  
  166. IS_MORE PROC    NEAR
  167. ; Test to see if more filespecs are on command line
  168.         MOV     SI,80H
  169.         XOR     CX,CX
  170.         MOV     CL,[SI]
  171.         MOV     DI,81H
  172.         ADD     DI,CX                   ; Set DI to end of command line
  173.         MOV     SI,[CMDLINE]
  174.         CMP     SI,DI
  175.         RET
  176. IS_MORE ENDP
  177.  
  178. SEARCH_DIRECTORY        PROC    NEAR
  179. ; This procedure searches all the files in the current directory looking for a match.
  180. ; It also prints the fill name for each match.
  181.  
  182. ;       DS:BX
  183. ;       DS:DX
  184.  
  185. ; Reads:        Disk Transfer Area (DTA)
  186. ; Writes:       Disk Transfer Area
  187. ; Calls:        BUILD_NAME, GET_FIRST_MATCH, WRITE_MATCHED_NAME, GET_NEXT_MATCH,
  188. ;               BUILD_STAR_NAME, SEARCH_SUB_DIRECTORY
  189.  
  190.         PUSH SI                         ; NEED TO RESTORE ON EXIT
  191.         PUSH DX
  192.         CALL BUILD_NAME                 ; Build the absolute search name
  193.         CALL GET_FIRST_MATCH            ; See if there is a match here
  194.         JC NO_MATCH                     ; no match, check subdirectories
  195.         CALL WRITE_MATCHED_NAME         ; write name of match
  196. FIND_NEXT_FILE:
  197.         CALL GET_NEXT_MATCH             ; find the next match
  198.         JC NO_MATCH                     ; no match, search subdirectories
  199.         CALL WRITE_MATCHED_NAME         ; match, grite absolute name
  200.         JMP FIND_NEXT_FILE              ; look for the next matching name
  201. NO_MATCH:
  202.         POP DX                          ; restore DTA
  203.         PUSH DX
  204.         CALL BUILD_STAR_NAME            ; search for all directories
  205.         CALL GET_FIRST_MATCH            ; get first entry
  206.         JC NO_MORE_MATCHES              ; there are no entries
  207.         MOV SI,DX                       ; put address of DTA into SI
  208.         TEST [SI].ATTRIBUTE,10H         ; is it a directory entry?
  209.         JNZ IS_DIRECTORY                ; yes, then search subdirectory
  210. FIND_NEXT_DIRECTORY:
  211.         CALL GET_NEXT_MATCH             ; no, then find the next match
  212.         JC NO_MORE_MATCHES              ; there are no more entries
  213.         TEST [SI].ATTRIBUTE,10H         ; is this a directory?
  214.         JZ FIND_NEXT_DIRECTORY          ; no, then try again
  215. IS_DIRECTORY:
  216.         CMP [SI].NAME_FOUND,'.'        ; is this a . or .. directory?
  217.         JE FIND_NEXT_DIRECTORY          ; yes, skip to next directory
  218.         CALL SEARCH_SUB_DIRECTORY       ; search the subdirectory
  219.         PUSH AX                         ; now reset the DTA
  220.         MOV AH,1AH
  221.         INT 21H
  222.         POP AX
  223.         JMP FIND_NEXT_DIRECTORY
  224. NO_MORE_MATCHES:
  225.         POP DX
  226.         POP SI
  227.         RET
  228. SEARCH_DIRECTORY        ENDP
  229.  
  230. SEARCH_SUB_DIRECTORY    PROC    NEAR
  231. ; This procedure searches the subdirectory whose name is in the DTA
  232. ; DS:BX         end of the current pathname
  233. ; ds:[dx].name_found    name of subdirectory for search
  234. ; reads:        path_name
  235. ; writes:       path_name
  236. ; calls:        search_directory
  237.         PUSH DI
  238.         PUSH SI
  239.         PUSH AX
  240.         PUSH BX
  241.         CLD
  242.         MOV SI,DX                       ; put address of DTA into SI
  243.         ADD SI,OFFSET NAME_FOUND        ; set to start of subdirectory name
  244.         MOV DI,BX
  245. COPY_LOOP:
  246.         LODSB
  247.         STOSB
  248.         OR AL,AL                        ; was it a 0
  249.         JNZ COPY_LOOP                   ; no, keep copying
  250.         MOV BX,DI                       ;set BX to end of new pathname
  251.         STD                             ; set flag for decrement
  252.         STOSB                           ; store a 0 at end of string
  253.         MOV AL,'\'
  254.         STOSB                           ; place '\' at end of pathname
  255.         CALL SEARCH_DIRECTORY           ; search this new path
  256.         POP BX                          ; restore the old end-of-paht
  257.         MOV BYTE PTR [BX],0             ; and store a zero here
  258.         POP AX
  259.         POP SI
  260.         POP DI
  261.         RET
  262. SEARCH_SUB_DIRECTORY    ENDP
  263.  
  264. WRITE_MATCHED_NAME      PROC NEAR
  265. ; This procedure prints the matched name after the path name
  266.         PUSH    AX
  267.         PUSH    DX
  268.         MOV     DL,[CURDRIVE]
  269.         ADD     DL,'A'        ; Convert to ASCII
  270.         MOV     AH,2
  271.         INT     21H
  272.         MOV     DL,':'
  273.         INT     21H
  274.         MOV     DX,OFFSET CG:PATH_NAME
  275.         MOV     AL,[BX]         ; Save character at end of path
  276.         MOV     BYTE PTR[BX],0  ; End of string mark
  277.         CALL    WRITE_STRING
  278.         MOV     [BX],AL
  279.         POP     DX
  280.         PUSH    DX              ; Restore old pointer
  281.         ADD     DX,OFFSET NAME_FOUND
  282.         CALL    WRITE_STRING
  283.         CALL    SEND_CRLF
  284.         INC     LINCTR                     ;inc line counter
  285.         MOV     AL,23                      ;test for 23 lines printed
  286.         CMP     AL,LINCTR
  287.         JNE     WRITEXIT                   ;no_normal exit
  288.         MOV     AL,0                       ;23 printed, so send
  289.         MOV     LINCTR,AL                  ;message
  290.         MOV     DX,OFFSET CG:PROMPT
  291.         MOV     AH,9
  292.         INT     21H
  293.         MOV     AH,0
  294.         INT     16H
  295.         CMP     AL,'N'
  296.         JE      DOS_EXIT
  297.         CMP     AL,'n'
  298.         JE      DOS_EXIT
  299. WRITEXIT:
  300.         POP     DX
  301.         POP     AX
  302.         RET
  303. WRITE_MATCHED_NAME      ENDP
  304.  
  305. BUILD_NAME      PROC    NEAR
  306.         PUSH    SI
  307.         MOV     SI,OFFSET CG:FILE_NAME
  308.         CALL    BUILD
  309.         POP     SI
  310.         RET
  311. BUILD_NAME      ENDP
  312.  
  313. BUILD_STAR_NAME PROC    NEAR
  314.         PUSH    SI
  315.         MOV     SI,OFFSET CG:STAR_NAME
  316.         CALL    BUILD
  317.         POP     SI
  318.         RET
  319. BUILD_STAR_NAME ENDP
  320.  
  321. BUILD   PROC    NEAR
  322.         PUSH    AX
  323.         PUSH    DI
  324.         MOV     DI,BX
  325.         CLD
  326. COPY_NAME:
  327.         LODSB
  328.         STOSB                   ; Get 1 character of name
  329.         OR      AL,AL           ; End of string ?
  330.         JNZ     COPY_NAME
  331.         POP     DI
  332.         POP     AX
  333.         RET
  334. BUILD   ENDP
  335.  
  336. GET_FIRST_MATCH PROC    NEAR
  337.         PUSH    CX
  338.         CMP     DX,0            ; 1st one ?
  339.         JA      ALLOCATE        ; No, then make some space
  340.         MOV     DX,OFFSET CG:DISK_TRANSFER_AREAS-TYPE DTA
  341. ALLOCATE:
  342.         ADD     DX,TYPE DTA     ; No,then allocate room for new DTA
  343.         MOV     CX,10H          ; Search attribute
  344.         MOV     AH,1AH
  345.         INT     21H
  346.         PUSH    DX
  347.         MOV     DX,OFFSET CG:PATH_NAME
  348.         MOV     AH,4EH          ; Call for "find first match"
  349.         INT     21H
  350.         POP     DX
  351.         POP     CX
  352.         RET
  353. GET_FIRST_MATCH ENDP
  354.  
  355. GET_NEXT_MATCH  PROC    NEAR
  356.         PUSH    CX
  357.         PUSH    DX
  358.         MOV     DX,OFFSET CG:PATH_NAME
  359.         MOV     CX,10H
  360.         MOV     AH,4FH
  361.         INT     21H
  362.         POP     DX
  363.         POP     CX
  364.         RET
  365. GET_NEXT_MATCH  ENDP
  366.  
  367. SEND_CRLF       PROC    NEAR
  368.         PUSH    AX
  369.         PUSH    DX
  370.         MOV     AH,2
  371.         MOV     DL,0AH
  372.         INT     21H
  373.         MOV     DL,0DH
  374.         INT     21H
  375.         POP     DX
  376.         POP     AX
  377.         RET
  378. SEND_CRLF       ENDP
  379.  
  380. WRITE_STRING    PROC    NEAR
  381.         PUSH    AX
  382.         PUSH    DX
  383.         PUSH    SI
  384.         CLD
  385.         MOV     SI,DX
  386.         MOV     AH,2
  387.         LODSB
  388. WRITE_STRING_LOOP:
  389.         MOV     DL,AL
  390.         INT     21H
  391.         LODSB
  392.         OR      AL,AL           ; End of string ?
  393.         JNZ     WRITE_STRING_LOOP
  394.         POP     SI
  395.         POP     DX
  396.         POP     AX
  397.         RET
  398. WRITE_STRING    ENDP
  399.  
  400. ERROR   PROC    NEAR
  401.         MOV     AH,9
  402.         INT     21H
  403.         RET                     ; Print message
  404. ERROR   ENDP
  405.  
  406. DOS_EXIT        PROC NEAR
  407.         MOV     DL,[OLDDRIV]
  408.         MOV     AH,0EH
  409.         INT     21H
  410.         MOV     AH,4CH
  411.         INT     21H
  412. DOS_EXIT        ENDP
  413.  
  414. GET_CHAR_COUNT  PROC    NEAR
  415.         PUSH    SI
  416.         MOV     SI,DX
  417.         XOR     CX,CX
  418. CHAR_COUNT:
  419.         LODSB
  420.         CMP     AL,' '
  421.         JBE     CHAR_COUNT_RET
  422.         INC     CX
  423.         JMP     CHAR_COUNT
  424. CHAR_COUNT_RET:
  425.         POP     SI
  426.         RET
  427. GET_CHAR_COUNT  ENDP
  428.  
  429.  
  430. PRINT_FILE_SEP  PROC    NEAR
  431.         PUSH    DX
  432.         PUSH    CX
  433.         MOV     DX,OFFSET CRLF_STR
  434.         MOV     AH,9
  435.         INT     21H
  436.         MOV     DX,OFFSET SEARCH_NAME
  437.         CALL    GET_CHAR_COUNT
  438.         PUSH    CX
  439.         MOV     BX,1
  440.         MOV     AH,40H
  441.         INT     21H                     ; Print search name
  442.         POP     CX                      ; How many characters in name ?
  443.         MOV     DX,OFFSET FILE_SEP
  444.         ADD     DX,CX
  445.         CALL    ERROR
  446.         POP     CX
  447.         POP     DX
  448.         RET
  449. PRINT_FILE_SEP  ENDP
  450.  
  451.  
  452. SCANOFF PROC    NEAR
  453.         PUSH    BX
  454.         PUSH    CX
  455. SCANOFF_CMP:
  456.         LODSB
  457.         CMP     AL,' '
  458.         JBE     SCANOFF_CMP
  459.         DEC     SI
  460. ; Don't go beyond command line
  461.         MOV     BX,80H
  462.         MOV     CL,[BX]
  463.         XOR     CH,CH
  464.         ADD     CX,81H
  465.         CMP     SI,CX
  466.         JB      SCANOFF_RET
  467.         MOV     SI,CX           ; Point to end of command line
  468.         STC
  469.         POP     CX
  470.         POP     BX
  471.         RET
  472. SCANOFF_RET:
  473.         CLC
  474.         POP     CX
  475.         POP     BX
  476.         RET
  477. SCANOFF ENDP
  478.  
  479. NEXT_BLANK      PROC    NEAR
  480. ; Set SI to point to next blank character
  481.         LODSB
  482.         CMP     AL,','
  483.         JA      NEXT_BLANK
  484.         DEC     SI
  485.         RET
  486. NEXT_BLANK      ENDP
  487.  
  488.  
  489. INVALID_DRIVE           DB 'Bad drive specified',13,10,'$'
  490. NONAME                  DB 'No filename specified',13,10,'$'
  491. WRONG_VERS              DB 'MS-DOS must be at least version 2.0',13,10,'$'
  492. FILE_SEP                DB '---------------------------------------------',13,10,'$'
  493. CRLF_STR                DB      13,10,'$'
  494. OLDDRIV                 DB  0
  495. CURDRIVE                DB  0
  496. FIRST                   DB  0
  497. LINCTR                  DB  0
  498. PROMPT                  DB ' More ?',0AH,0DH,'$'
  499. CMDLINE                 DW      81H
  500. STAR_NAME               DB '*.*',0
  501. PATH_NAME               DB '\',0
  502.                         DB 80 DUP (0)   ; space for 64 character pathname and 13 character filename
  503. FILE_NAME               DB 13 DUP (0)
  504. SEARCH_NAME             DB 13 DUP (0)
  505. DISK_TRANSFER_AREAS     LABEL BYTE
  506.  
  507. CODE_SEG        ENDS
  508.  
  509.                 END     START
  510.